import urllib2

import sqlalchemy

from sqlalchemy import orm
from model import DeclarativeBase

__all__ = ['ImageHost']


class ImageHost(DeclarativeBase):
    """
    Information of image in the corresponding host.

    Attributes:
        - image_id: An integer for image primary key.
        - host_id: An integer for host primary key.
        - original_id: An integer of image id on host.
        - dateTime: A date time when image uploaded to host.
        - url: A string where image located.
    """

    __tablename__ = 'images_hosts'

    id = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True)
    """
    The primary key.

    @type: int
    """

    image_id = sqlalchemy.Column(sqlalchemy.Integer,
                                 sqlalchemy.ForeignKey("images.id"),
                                 nullable=False, index=True)
    """
    Image primary key.

    @type: int
    """

    host_id = sqlalchemy.Column(sqlalchemy.Integer,
                                sqlalchemy.ForeignKey('hosts.id'),
                                nullable=False, index=True)
    """
    Host primary key.

    @type: int
    """

    original_id = sqlalchemy.Column(sqlalchemy.Integer)
    """
    Original Id in the corresponding host.

    @type: int
    """

    date_time = sqlalchemy.Column(sqlalchemy.DateTime)
    """
    Date time when image uploaded to the corresponding host.

    @type: datetime
    """

    url = sqlalchemy.Column(sqlalchemy.String(2000))
    """
    Location where image located.

    @type: str
    """

    image = orm.relationship('Image', uselist=False,
                             backref=orm.backref('image_hosts'))
    """
    The Image instance of image_id.

    @type: model.Image
    """

    host = orm.relationship('Host', uselist=False,
                            backref=orm.backref('image_hosts'))
    """
    The Host instance of host_id.

    @type: model.Host
    """

    def __init__(self, post=None):
        """
        Initialize ImageHost.

        @param post: Post object for ImageHost.
        @type post: model.Post or None

        @return: None
        @rtype: None
        """

        super(ImageHost, self).__init__()

        if post:
            self.original_id = post.id
            self.date_time = post.created_at
            self.url = post.url
            self.host = post.host

    def download(self, report_hook=None):
        """
        Download image file form host.

        @param report_hook: A function that will be call periodically when
            download is in progress. The function must have two arguments of
            total and progress.
        @type report_hook: function
        """

        counter = 0
        block = 1024
        temp_file = open(self.post.temp.path, 'wb')

        url = self.url
        if url[0:4].lower() != 'http':
            url = '%s%s' % (self.host.url, self.url)
        request = urllib2.Request(url)
        request.add_header('Referer', self.host.url)

        url = urllib2.urlopen(request, timeout=30)
        meta = url.info()
        size = 0
        if 'Content-Length' in meta:
            size = long(meta.getheader('Content-Length'))

        if report_hook:
            report_hook(size, 1)

        for chunk in iter(lambda: url.read(block), ''):
            counter += 1
            temp_file.write(chunk)
            if report_hook:
                report_hook(size, counter * block)

        temp_file.close()

        return True
